home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / umddvi / lib / pkfont.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  18KB  |  768 lines

  1. /*
  2.  * Copyright (c) 1987 University of Maryland Department of Computer Science.
  3.  * All rights reserved.  Permission to copy for any purpose is hereby granted
  4.  * so long as this copyright notice remains intact.
  5.  */
  6.  
  7. #ifndef lint
  8. static char rcsid[] = "$Header: pkfont.c,v 2.8 87/08/21 12:44:28 chris Exp $";
  9. #endif
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include "types.h"
  15. #include "font.h"
  16. #include "num.h"
  17.  
  18. /*
  19.  * PK font operations.
  20.  *
  21.  * The spelling `nybble' is a concession to the authors of the PK format.
  22.  */
  23. int    pk_read(), pk_getgly(), pk_rasterise(), pk_freefont();
  24.  
  25. struct    fontops pkops =
  26.     { "pk", 1.0, pk_read, pk_getgly, pk_rasterise, pk_freefont };
  27.  
  28. /*
  29.  * Local info.
  30.  */
  31.  
  32. /*
  33.  * Commands.
  34.  */
  35. #define    PK_XXX1        240    /* 1 byte special */
  36. #define    PK_XXX2        241    /* 2 byte special */
  37. #define    PK_XXX3        242    /* 3 byte special */
  38. #define    PK_XXX4        243    /* 4 byte special */
  39. #define    PK_YYY        244    /* METAFONT numspecial */
  40. #define    PK_POST        245    /* marks postamble */
  41. #define    PK_NO_OP    246    /* do nothing */
  42. #define    PK_PRE        247    /* marks preamble */
  43.                 /* 248..255 undefined */
  44. #define PK_IsUndef(c)    ((c) > PK_PRE)
  45.  
  46. #define    PK_ID        89    /* marks this brand of PK file */
  47.  
  48. /*
  49.  * Information about a character packet.
  50.  */
  51. struct cp {
  52.     char    *cp_packet;    /* the beginning of the packet */
  53.     int    cp_type;    /* decoded pre type, see below */
  54. };
  55.  
  56. #define    CP_SHORT    0    /* short preamble */
  57. #define    CP_EXT_SHORT    1    /* extended short preamble */
  58. #define    CP_LONG        2    /* long preamble */
  59.  
  60. /*
  61.  * The PK details include:
  62.  *  ->    a pointer to the next byte to fetch;
  63.  *  ->    the most recent byte fetched (when we are using nextnyb());
  64.  *  ->    a flag indicating that we have used nybble 0 (bits 4..7) and
  65.  *    should use nybble 1 next;
  66.  *  ->    the base address of the memory allocated for the PK file;
  67.  *  ->    the value of dyn_f (during character translation);
  68.  *  ->    the repeat count (during rasterisation);
  69.  *  ->    the lowest glyph number that is legal;
  70.  *  ->    the highest glyph number that is legal;
  71.  *  ->    glyph instructions for the standard glyphs;
  72.  *  ->    glyph instructions for more (nonstandard) glyphs;
  73.  * and    the number of glyphs left unrasterised.
  74.  */
  75. struct pk_details {
  76.     char    *pk_ptr;    /* next byte to fetch */
  77.     int    pk_c;        /* most recent byte fetched, if nybbling */
  78.     int    pk_1nyb;    /* true => nybble 1 is next (bits 0..3) */
  79.     char    *pk_base;    /* base of allocated memory */
  80.     int    pk_dyn_f;    /* the dyn_f value */
  81.     int    pk_repeat;    /* the repeat count */
  82.     int    pk_minc;    /* minimum character value */
  83.     int    pk_maxc;    /* maximum character value */
  84. #define MAXSTD    256        /* maximum `standard' character value */
  85.     int    pk_gleft;    /* number of valid glyphs left uninterpreted */
  86.     struct    cp pk_cpack[MAXSTD];    /* for characters in [0..MAXSTD) */
  87.     struct    cp *pk_morec;        /* for characters in [MAXSTD..maxc] */
  88. };
  89.  
  90. /*
  91.  * Fetch the next byte from the PK file.
  92.  */
  93. #define    nextbyte(pk) pgetbyte((pk)->pk_ptr)
  94.  
  95. /*
  96.  * PK packed number encoding.  Nybbles in [1..dyn_f] represent themselves.
  97.  * Values in (dyn_f..13] are two-nybble values, and represent values
  98.  * dyn_f+1 through (13-dyn_f+1)*16+15.  Zero marks a long number; 14 and
  99.  * 15 specify repeat counts instead (which are another packed number).
  100.  * Note that we cannot represent the number zero as a packed number.
  101.  */
  102. #define    PK_LONGNUM    0    /* a `long number' */
  103. #define    PK_REPEAT    14    /* set repeat count */
  104. #define    PK_REPEAT1    15    /* set repeat to 1 */
  105.  
  106. /*
  107.  * Get the next nybble.  This is an expression rendition of
  108.  *    if (--pk->pk_1nyb < 0) {
  109.  *        pk->pk_1nyb = 1;
  110.  *        pk->pk_c = nextbyte(pk);
  111.  *        return (pk->pk_c >> 4);
  112.  *    } else
  113.  *        return (pk->pk_c & 0xf);
  114.  */
  115. #define    nextnyb(f) \
  116.     (--(pk)->pk_1nyb < 0 ? \
  117.      ((pk)->pk_1nyb = 1, ((pk)->pk_c = nextbyte(pk)) >> 4) : \
  118.      (pk)->pk_c & 0xf)
  119.  
  120. /*
  121.  * Get the pk_details from font f.
  122.  */
  123. #define    ftopk(f) ((struct pk_details *) (f)->f_details)
  124.  
  125. extern    int errno;
  126. char    *malloc();
  127.  
  128. /*
  129.  * PK subroutines.
  130.  */
  131.  
  132. /*
  133.  * Unpack a packed number.
  134.  */
  135. static int
  136. pk_unpack(pk)
  137.     register struct pk_details *pk;
  138. {
  139.     register int i, j;
  140.  
  141. top:
  142.     if ((i = nextnyb(pk)) == PK_LONGNUM) {
  143. #if PK_LONGNUM != 0        /* this may be silly, but . . . */
  144.         i = 0;
  145. #endif
  146.         /*
  147.          * Expand a long number.  There are one fewer leading
  148.          * zeros than there are nonzero digits to obtain, so
  149.          * count up the leading zeros, add one, and get that
  150.          * many digits.  (The `digits' are hexadecimal values.)
  151.          */
  152.         do {
  153.             i++;
  154.         } while ((j = nextnyb(pk)) == 0);
  155.         while (--i >= 0) {
  156.             j <<= 4;
  157.             j += nextnyb(pk);
  158.         }
  159.         return (j - 15 + (13 - pk->pk_dyn_f) * 16 + pk->pk_dyn_f);
  160.     }
  161.     if (i <= pk->pk_dyn_f)
  162.         return (i);
  163.     if (i < PK_REPEAT)
  164.         return ((i - pk->pk_dyn_f - 1) * 16 + nextnyb(pk) +
  165.             pk->pk_dyn_f + 1);
  166.  
  167.     /*
  168.      * There is a repeat count, either one or a packed number.
  169.      * Get it first, then start over.  (tail recursion)
  170.      */
  171.     if (i == PK_REPEAT)
  172.         pk->pk_repeat = pk_unpack(pk);
  173.     else
  174.         pk->pk_repeat = 1;
  175.     goto top;
  176. }
  177.  
  178. /*
  179.  * Skip over special commands (PK_XXX?, PK_YYY).
  180.  */
  181. static
  182. skip_specials(f)
  183.     struct font *f;
  184. {
  185.     struct pk_details *pk = ftopk(f);
  186.     register char *p = pk->pk_ptr;
  187.     register i32 i;
  188.  
  189.     for (;;) {
  190.         switch (UnSign8(*p++)) {
  191.  
  192.         case PK_XXX1:
  193.             i = UnSign8(*p++);
  194.             p += i;
  195.             break;
  196.  
  197.         case PK_XXX2:
  198.             pGetWord(p, i);
  199.             p += i;
  200.             break;
  201.  
  202.         case PK_XXX3:
  203.             pGet3Byte(p, i);
  204.             p += i;
  205.             break;
  206.  
  207.         case PK_XXX4:
  208.             pGetLong(p, i);
  209.             p += i;
  210.             break;
  211.  
  212.         case PK_YYY:
  213.             p += 4;
  214.             break;
  215.  
  216.         case PK_NO_OP:
  217.             break;
  218.  
  219.         case PK_PRE:
  220.             error(1, 0, "unexpected PK_PRE in \"%s\"", f->f_path);
  221.             break;
  222.  
  223.         default:
  224.             p--;
  225.             if (PK_IsUndef(UnSign8(*p)))
  226.                 error(1, 0, "invalid opcode %d in \"%s\"",
  227.                     f->f_path);
  228.             pk->pk_ptr = p;
  229.             return;
  230.         }
  231.     }
  232. }
  233.  
  234. /*
  235.  * Read a PK file.
  236.  */
  237. static int
  238. pk_read(f)
  239.     register struct font *f;
  240. {
  241.     register struct pk_details *pk;
  242.     register char *p;
  243.     int i, fd, minc;
  244.     struct stat st;
  245.     char *reason;
  246.  
  247.     if ((fd = open(f->f_path, 0)) < 0)
  248.         return (-1);
  249.     pk = NULL;        /* prepare for failure */
  250.     reason = NULL;
  251.     (void) fstat(fd, &st);
  252.     if (st.st_size < 4) {    /* ??? */
  253.         reason = "file is too small";
  254.         goto fail;
  255.     }
  256.     if ((pk = (struct pk_details *) malloc(sizeof (*pk))) == NULL)
  257.         goto fail;
  258.     pk->pk_morec = NULL;
  259.     if ((pk->pk_base = malloc(st.st_size)) == NULL)
  260.         goto fail;
  261.     if (read(fd, pk->pk_base, st.st_size) != st.st_size)
  262.         goto fail;
  263.     pk->pk_ptr = pk->pk_base;
  264.     if (nextbyte(pk) != PK_PRE) {
  265.         reason = "file does not begin with PK_PRE";
  266.         goto fail;
  267.     }
  268.     if (nextbyte(pk) != PK_ID) {
  269.         reason = "bad PK_ID";
  270.         goto fail;
  271.     }
  272.     i = nextbyte(pk);
  273.     p = pk->pk_ptr + i + 4;    /* skip comment and design size */
  274.     pGetLong(p, f->f_checksum);
  275.     pk->pk_ptr = p + 4 + 4;    /* skip hppp, vppp */
  276.  
  277.     f->f_details = (char *) pk;
  278.  
  279.     /* scan the characters, fail if necessary */
  280.     if (scan_characters(f, &reason))
  281.         goto fail;
  282.  
  283.     /* ignore the postamble */
  284.  
  285.     /* COMPRESS pk->pk_base DATA? */
  286.  
  287.     if (FontHasGlyphs(f, pk->pk_minc, pk->pk_maxc + 1))
  288.         goto fail;
  289.     (void) close(fd);
  290.     return (0);
  291.  
  292. fail:
  293.     if (reason) {
  294.         error(0, 0, "%s", reason);
  295.         error(0, 0, "(are you sure %s is a PK file?)", f->f_path);
  296.         errno = 0;
  297.     }
  298.     if (pk != NULL) {
  299.         if (pk->pk_base != NULL)
  300.             free(pk->pk_base);
  301.         if (pk->pk_morec != NULL)
  302.             free((char *) pk->pk_morec);
  303.         free((char *) pk);
  304.     }
  305.     (void) close(fd);
  306.     return (-1);
  307. }
  308.  
  309. /*
  310.  * Scan through the characters in the PK file, and set the offsets
  311.  * and preamble types for each of the character packets.
  312.  */
  313. static int
  314. scan_characters(f, reason)
  315.     struct font *f;
  316.     char **reason;
  317. {
  318.     register struct pk_details *pk = ftopk(f);
  319.     register i32 c, pl;
  320.     register char *p;
  321.     register struct cp *cp;
  322.     int type;
  323.  
  324. #ifdef lint
  325.     /* reason will be used someday ... I think */
  326.     reason = reason;
  327. #endif
  328.  
  329.     /* set up the minimisers and the glyph count */
  330.     pk->pk_minc = 1;
  331.     pk->pk_maxc = 0;
  332.     pk->pk_gleft = 0;
  333.  
  334.     /* mark all character packets as untouched */
  335.     for (cp = pk->pk_cpack, c = MAXSTD; --c >= 0; cp++)
  336.         cp->cp_packet = NULL;
  337.  
  338.     /*
  339.      * Loop through the packets until we reach a POST, skipping
  340.      * the glyph instructions themselves after each definition,
  341.      * and specials (if any) before each.
  342.      */
  343.     for (;; pk->pk_ptr = p + pl) {
  344.         skip_specials(f);
  345.         p = pk->pk_ptr;
  346.         if ((c = pgetbyte(p)) == PK_POST)
  347.             break;    /* whoops, done after all */
  348.  
  349.         /*
  350.          * Look at the low three bits to decide preamble size.
  351.          * A value of 7 is a `long preamble'; 4, 5, and 6 are
  352.          * `extended short preambles'; and 0, 1, 2, and 3 are
  353.          * `short preambles'.
  354.          *
  355.          * We ignore most of the preamble, reading only the
  356.          * `packet length' and the character code at this time.
  357.          */
  358.         switch (c & 7) {
  359.  
  360.         case 7:        /* long */
  361.             type = CP_LONG;
  362.             pGetLong(p, pl);
  363.             pGetLong(p, c);
  364.             break;
  365.  
  366.         case 6:
  367.         case 5:
  368.         case 4:        /* extended short */
  369.             type = CP_EXT_SHORT;
  370.             pGetWord(p, pl);
  371.             pl += (c & 3) << 16;
  372.             c = pgetbyte(p);
  373.             break;
  374.  
  375.         default:    /* short */
  376.             type = CP_SHORT;
  377.             pl = ((c & 3) << 8) + pgetbyte(p);
  378.             c = pgetbyte(p);
  379.             break;
  380.         }
  381.  
  382.         if (c >= MAXSTD) {
  383.             /*
  384.              * BEGIN XXX - should alloc pk_morec, but is hard
  385.              * and not now useful
  386.              */
  387.             error(0, 0, "ignoring character %d in \"%s\"",
  388.                 f->f_path);
  389.             error(0, 0, "because some darn programmer was lazy!");
  390.             continue;
  391.             /* END XXX */
  392.         } else
  393.             cp = &pk->pk_cpack[c];
  394.  
  395.         cp->cp_packet = pk->pk_ptr;
  396.         cp->cp_type = type;
  397.  
  398.         /* adjust range */
  399.         if (c < pk->pk_minc)
  400.             pk->pk_minc = c;
  401.         if (c > pk->pk_maxc)
  402.             pk->pk_maxc = c;
  403.  
  404.         pk->pk_gleft++;    /* and count the glyph */
  405.     }
  406.     return (0);        /* no problems */
  407. }
  408.  
  409. /*
  410.  * Obtain the specified range of glyphs.
  411.  */
  412. static int
  413. pk_getgly(f, l, h)
  414.     register struct font *f;
  415.     int l, h;
  416. {
  417.     register struct pk_details *pk = ftopk(f);
  418.     register char *p;
  419.     register struct glyph *g;
  420.     register int i;
  421.     register struct cp *cp;
  422.  
  423.     if (pk == NULL)
  424.         panic("pk_getgly(%s)", f->f_path);
  425.     for (i = l; i < h; i++) {
  426.         if (i < MAXSTD)
  427.             cp = &pk->pk_cpack[i];
  428.         else {
  429.             if (i > pk->pk_maxc)
  430.                 panic("pk_getgly(%s, %d)", f->f_path, i);
  431.             cp = &pk->pk_morec[i - MAXSTD];
  432.         }
  433.         p = cp->cp_packet;
  434.         if (p == NULL)    /* glyph is not valid */
  435.             continue;
  436.         g = f->f_gly[i];
  437.         p++;        /* skip flag */
  438.         switch (cp->cp_type) {
  439.  
  440.         case CP_LONG:
  441.             p += 8;    /* skip packet len, character code */
  442.             pGetLong(p, g->g_tfmwidth);
  443. #ifdef notyet
  444.             pGetLong(p, g->g_xescapement);
  445.             pGetLong(p, g->g_yescapement);
  446. #else
  447.             p += 8;
  448. #endif
  449.             pGetLong(p, g->g_width);
  450.             pGetLong(p, g->g_height);
  451.             pGetLong(p, g->g_xorigin);
  452.             pGetLong(p, g->g_yorigin);
  453.             break;
  454.  
  455.         case CP_EXT_SHORT:
  456.             p += 3;    /* skip packet len, character code */
  457.             pGet3Byte(p, g->g_tfmwidth);
  458. #ifdef notyet
  459.             { i32 dm; pGetWord(p, dm);
  460.             g->g_xescapement = dm << 16; }
  461.             g->g_yescapement = 0;
  462. #else
  463.             p += 2;    /* skip dm */
  464. #endif
  465.             pGetWord(p, g->g_width);
  466.             pGetWord(p, g->g_height);
  467.             pGetWord(p, g->g_xorigin);
  468.             g->g_xorigin = Sign16(g->g_xorigin);
  469.             pGetWord(p, g->g_yorigin);
  470.             g->g_yorigin = Sign16(g->g_yorigin);
  471.             break;
  472.  
  473.         case CP_SHORT:
  474.             p += 2;    /* skip packet len, character code */
  475.             pGet3Byte(p, g->g_tfmwidth);
  476. #ifdef notyet
  477.             g->g_xescapement = pgetbyte(p) << 16;
  478.             g->g_yescapement = 0;
  479. #else
  480.             p++;    /* skip dm */
  481. #endif
  482.             g->g_width = pgetbyte(p);
  483.             g->g_height = pgetbyte(p);
  484.             g->g_xorigin = pgetbyte(p);
  485.             g->g_xorigin = Sign8(g->g_xorigin);
  486.             g->g_yorigin = pgetbyte(p);
  487.             g->g_yorigin = Sign8(g->g_yorigin);
  488.             break;
  489.         }
  490.         g->g_flags = GF_VALID;
  491.         g->g_un.g_details = p;
  492.     }
  493.     return (0);
  494. }
  495.  
  496. /*
  497.  * Bit masks for pk_rasterise().
  498.  */
  499. static char bmask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
  500. static char rbits[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  501.  
  502. /*
  503.  * Obtain rasters for the specified glyphs.
  504.  */
  505. static int
  506. pk_rasterise(f, l, h)
  507.     struct font *f;
  508.     int l, h;
  509. {
  510.     struct pk_details *pk0;
  511.     struct glyph *g0;
  512.     char *p0, *rp0;
  513.     int flag, ii;
  514.  
  515.     if ((pk0 = ftopk(f)) == NULL)
  516.         panic("pk_rasterise(%s)", f->f_path);
  517.     for (ii = l; ii < h; ii++) {
  518.         {
  519.             register struct glyph *g;
  520.             register char *p;
  521.             register int i;
  522.  
  523.             g = f->f_gly[i = ii];
  524.             if ((g->g_flags & GF_VALID) == 0)
  525.                 continue;    /* no glyph */
  526.             if (!HASRASTER(g))    /* empty raster */
  527.                 goto done;
  528.  
  529.             /*
  530.              * Allocate a raster.
  531.              */
  532.             rp0 = malloc(((g->g_width + 7) >> 3) * g->g_height);
  533.             if ((g->g_raster = rp0) == NULL)
  534.                 return (-1);/* ??? */
  535.             g->g_rotation = ROT_NORM;
  536.  
  537.             /*
  538.              * Pick up the flag byte, then start at the real
  539.              * packet, which we saved in g_details.
  540.              */
  541.             if (i < MAXSTD)
  542.                 p = pk0->pk_cpack[i].cp_packet;
  543.             else
  544.                 p = pk0->pk_morec[i - MAXSTD].cp_packet;
  545.             flag = UnSign8(*p);
  546.             p0 = g->g_un.g_details;
  547.             g0 = g;
  548.         }
  549.         if ((pk0->pk_dyn_f = flag >> 4) == 14) {
  550.             register char *p = p0, *rp = rp0;
  551.             register int j, ls, rs, i, w;
  552.  
  553.             /*
  554.              * Expand a bit-packed representation.
  555.              * If we get lucky, it is byte packed and
  556.              * we can just copy it over.
  557.              */
  558.             i = g0->g_height;
  559.             j = g0->g_width;
  560.             if ((j & 7) == 0) {
  561.                 bcopy(p, rp, i * (j >> 3));
  562.                 goto done;
  563.             }
  564.  
  565.             /*
  566.              * No such luck.
  567.              */
  568.             w = j;
  569.             ls = 0;
  570.             while (--i >= 0) {
  571. #if defined(vax) && !defined(lint)
  572.                 /* have to work on the compiler someday */
  573.                 rs = ls - 8;
  574. #else
  575.                 rs = 8 - ls;
  576. #endif
  577.                 /* know j always != 8 */
  578.                 for (j = w; j > 8; j -= 8) {
  579. #if defined(vax) && !defined(lint)
  580.                     asm("    movb    (r11)+,r0");
  581.                     asm("    ashl    r8,r0,r0");
  582.                     asm("    movb    r0,(r10)");
  583.                     asm("    movzbl    (r11),r0");
  584.                     asm("    ashl    r7,r0,r0");
  585.                     asm("    bisb2    r0,(r10)+");
  586. #else
  587.                     *rp = *p++ << ls;
  588.                     *rp++ |= UnSign8(*p) >> rs;
  589. #endif
  590.                 }
  591.  
  592.                 /*
  593.                  * We need j more bits; there are rs
  594.                  * bits available at *p.  Ask for j,
  595.                  * which gets min(j, rs).
  596.                  */
  597. #if defined(vax) && !defined(lint)
  598.                 /*void*/; /* avoid asm() label botch */
  599.                 asm("    movb    (r11),r0");
  600.                 asm("    ashl    r8,r0,r0");
  601.                 asm("    mcomb    _bmask[r9],r1");
  602.                 asm("    bicb2    r1,r0");
  603.                 asm("    movb    r0,(r10)+");
  604. #else
  605.                 *rp++ = (*p << ls) & bmask[j];
  606. #endif
  607.                 /* account for j bits */
  608.                 ls += j; ls &= 7;
  609.                 /* then adjust j based on rs */
  610. #if defined(vax) && !defined(lint)
  611.                 j += rs;
  612. #else
  613.                 j -= rs;
  614. #endif
  615.                 /* still need j more bits */
  616.                 if (j < 0)    /* got them all */
  617.                     continue;
  618.                 p++;
  619.                 if (j == 0)    /* there were just enough */
  620.                     continue;
  621.                 /* take j more bits */
  622. #if defined(vax) && !defined(lint)
  623.                 /*void*/; /* avoid asm() label botch */
  624.                 asm("    mcomb    _bmask[r9],r0");
  625.                 asm("    bicb3    r0,(r11),r0");
  626.                 asm("    movzbl    r0,r0");
  627.                 asm("    ashl    r7,r0,r0");
  628.                 asm("    bisb2    r0,-1(r10)");
  629. #else
  630.                 rp[-1] |= UnSign8(*p & bmask[j]) >> rs;
  631. #endif
  632.             }
  633.         } else {
  634.             register struct pk_details *pk = pk0;
  635.             register int on = flag & 8 ? 0xff : 0;
  636.             register char *rowp;    /* pointer into this row */
  637.             register int j;        /* trimmed run count */
  638.             register int k;        /* misc */
  639.             register int b;        /* bit index in current col */
  640.             register int i;        /* run count */
  641.             register int colsleft;    /* columns left this row */
  642.             register int rowsleft;    /* rows left */
  643.             static char *row;    /* a one-row buffer */
  644.             static int rowsize;    /* and its size in bytes */
  645.             int wb;            /* row width in bytes */
  646.  
  647.             wb = (g0->g_width + 7) >> 3;
  648.             if (rowsize < wb) {    /* get more row space */
  649.                 if (row)
  650.                     free(row);
  651.                 /* keep a slop byte */
  652.                 row = malloc((unsigned) (wb + 1));
  653.                 if (row == NULL)
  654.                     return (-1);    /* ??? */
  655.                 rowsize = wb;
  656.             }
  657.             bzero(row, wb);
  658.             rowsleft = g0->g_height;
  659.             colsleft = g0->g_width;
  660.             pk->pk_repeat = 0;
  661.             pk->pk_ptr = p0;
  662.             pk->pk_1nyb = 0;    /* start on nybble 0 */
  663.             rowp = row;
  664.             b = 0;
  665.             while (rowsleft > 0) {    /* do all rows */
  666.                 /* EXPAND IN LINE? */
  667.                 i = pk_unpack(pk);
  668.                 /*
  669.                  * Work until the run count is exhausted
  670.                  * (or at least pretty tired).
  671.                  *
  672.                  * (Okay, so the joke is stolen!)
  673.                  */
  674.                 while ((j = i) > 0) {
  675.                     /*
  676.                      * If the count is more than the
  677.                      * rest of this row, trim it down.
  678.                      */
  679.                     if (j > colsleft)
  680.                         j = colsleft;
  681.                     i -= j;    /* call them done */
  682.                     /*
  683.                      * We need k=8-b bits to finish
  684.                      * up the current byte.  If we
  685.                      * can finish it, do so; the proper
  686.                      * bits to set are in rbits[k].
  687.                      */
  688.                     if (j >= (k = 8 - b)) {
  689.                         j -= k;
  690.                         colsleft -= k;
  691.                         *rowp++ |= on & rbits[k];
  692.                         b = 0;
  693.                     }
  694.                     /*
  695.                      * Set any full bytes.
  696.                      */
  697.                     while (j >= 8) {
  698.                         *rowp++ = on;
  699.                         j -= 8;
  700.                         colsleft -= 8;
  701.                     }
  702.                     /*
  703.                      * Finally, begin a new byte, or
  704.                      * add to the current byte, with
  705.                      * j more bits.  We know j <= 8-b.
  706.                      * (If j==0, we may be writing on
  707.                      * our slop byte, which is why we
  708.                      * keep one around....)
  709.                      */
  710. if (j > 8-b) panic("pk_rasterise j>8-b");
  711.                     *rowp |= (on & bmask[j]) >> b;
  712.                     colsleft -= j;
  713.                     b += j; b &= 7;
  714.                     if (colsleft == 0) {
  715.                         pk->pk_repeat++;
  716.                         rowsleft -= pk->pk_repeat;
  717.                         while (--pk->pk_repeat >= 0) {
  718.                             bcopy(row, rp0, wb);
  719.                             rp0 += wb;
  720.                         }
  721. if (rowsleft == 0 && i) panic("pk_rasterise leftover bits");
  722.                         pk->pk_repeat = 0;
  723.                         rowp = row;
  724.                         colsleft = g0->g_width;
  725.                         bzero(row, wb);
  726.                         b = 0;
  727.                     }
  728.                 }
  729.                 on = 0xff - on;
  730.             }
  731.         }
  732.  
  733. done:
  734.         /*
  735.          * Successfully converted another glyph.
  736.          */
  737.         pk0->pk_gleft--;
  738.     }
  739.  
  740. if (pk0->pk_gleft < 0)
  741. panic("%s: gleft==%d", f->f_path, pk0->pk_gleft);
  742.     if (pk0->pk_gleft == 0) {
  743.         free(pk0->pk_base);
  744.         if (pk0->pk_morec != NULL)
  745.             free((char *) pk0->pk_morec);
  746.         free((char *) pk0);
  747.         f->f_details = NULL;
  748.     }
  749.     return (0);
  750. }
  751.  
  752. /*
  753.  * Discard the font details.
  754.  */
  755. static
  756. pk_freefont(f)
  757.     struct font *f;
  758. {
  759.     register struct pk_details *pk = ftopk(f);
  760.  
  761.     if (pk != NULL) {
  762.         free(pk->pk_base);
  763.         if (pk->pk_morec != NULL)
  764.             free((char *) pk->pk_morec);
  765.         free((char *) pk);
  766.     }
  767. }
  768.